package logic;

import java.util.Vector;


import editor.Grid;
import editor.ObjContainer;
import editor.Menu.OGGETTI;
import gameObjects.Bike.POINTTO;
import gameObjects.BikeCOM.TURNDIRECTION;

public class TargetFinder {
	private ObjContainer target;
	private float 		 posX,posY;
	private OGGETTI[][]  cells = Grid.getGrid();
	public TargetFinder()
	{
		this.target=new ObjContainer(-1,-1,null);
	}
	
	public ObjContainer getTarget()
	{
		return target;
	}
	
	public TURNDIRECTION followTarget(POINTTO direction, float x, float y)
	{
		this.setInteger(x,y,direction);
		if((target.getX()==-1 && target.getY()==-1)||
			isTooFar(x,y,direction))
		{
			target=lookForTarget(direction, x, y);
		}
		else
		{
			System.out.println("STO SEGUENDO: "+target.getType());
			if(posX==target.getX()&&posY==target.getY())
			{
				target = new ObjContainer(-1,-1, null);
			}
			else{
				switch(direction)
				{
				case NORTH:
					posX=(int)x;
					posY=(int)y;
					if(posY==target.getY())
					{
						if(posX>target.getX())
						{
							if(cells[(int)posX-1][(int)posY]!=OGGETTI.WALL && cells[(int)posX-1][(int)posY]!=OGGETTI.EXTWALL)
								return TURNDIRECTION.RIGHT;
						}
						if(posX<target.getX()){
							if(cells[(int)posX+1][(int)posY]!=OGGETTI.WALL && cells[(int)posX+1][(int)posY]!=OGGETTI.EXTWALL)
								return TURNDIRECTION.LEFT;
						}
					}
					break;
				case SOUTH:
					posX=(int)x;
					posY=(int)y;
					if(posY==target.getY())
					{
						if(posX>target.getX())
						{
							if(cells[(int)posX-1][(int)posY]!=OGGETTI.WALL && cells[(int)posX-1][(int)posY]!=OGGETTI.EXTWALL)
								return TURNDIRECTION.LEFT;
						}
						if(posX<target.getX())
						{
							if(cells[(int)posX+1][(int)posY]!=OGGETTI.WALL && cells[(int)posX+1][(int)posY]!=OGGETTI.EXTWALL)
								return TURNDIRECTION.RIGHT;
						}
					}
					break;
				case EAST:
					posX=(int)x;
					posY=(int)y;
					if(posX==target.getX())
					{
						if(posY>target.getY())
						{
							if(cells[(int)posX][(int)posY-1]!=OGGETTI.WALL && cells[(int)posX][(int)posY-1]!=OGGETTI.EXTWALL)
								return TURNDIRECTION.RIGHT;
						}
						if(posY<target.getY())
						{
							if(cells[(int)posX][(int)posY+1]!=OGGETTI.WALL && cells[(int)posX][(int)posY+1]!=OGGETTI.EXTWALL)
							return TURNDIRECTION.LEFT;
						}
					}
					break;
				case WEST:
					posX=(int)x;
					posY=(int)y;
					if(posX==target.getX())
					{
						if(posY>target.getY())
						{
							if(cells[(int)posX][(int)posY-1]!=OGGETTI.WALL && cells[(int)posX][(int)posY-1]!=OGGETTI.EXTWALL)
								return TURNDIRECTION.LEFT;
						}
						if(posY<target.getY())
						{
							if(cells[(int)posX][(int)posY+1]!=OGGETTI.WALL && cells[(int)posX][(int)posY+1]!=OGGETTI.EXTWALL)
								return TURNDIRECTION.RIGHT;
						}
					}
					break;
				}//chiude switch
			}//chiude else innestato
		}//chiude else esterno
		return TURNDIRECTION.AWAY;
	}
	
	private ObjContainer lookForTarget(POINTTO direction, float x, float y)
	{
		ObjContainer target= null;
		Vector<ObjContainer>closerTarget=new Vector<ObjContainer>();
		switch(direction)
		{
		case NORTH:
			posX=(int)x;
			posY=(int)y;
			for(int i=0;i<Grid.objs.size();i++)
			{
				target = new ObjContainer(Grid.objs.get(i).getCoords(), Grid.objs.get(i).getType());
				if(target.getType()==OGGETTI.KEY)
				{
					if((Math.abs(target.getX()-posX)<4)&&(target.getY()-posY<8)&&(target.getY()-posY>=0))
						closerTarget.add(target);
				}
				else
				{
					if((Math.abs(target.getX()-posX)<16)&&(target.getY()-posY<32)&&(target.getY()-posY)>=0)
						closerTarget.add(target);
				}
					
			}
			break;
		case SOUTH:
			posX=(int)x;
			posY=(int)y;
			for(int i=0;i<Grid.objs.size();i++)
			{
				target = new ObjContainer(Grid.objs.get(i).getCoords(), Grid.objs.get(i).getType());
				if(target.getType()==OGGETTI.KEY)
				{
					if((Math.abs(target.getX()-posX)<4)&&(posY-target.getY()<8)&&(posY-target.getY()>=0))
						closerTarget.add(target);
				}
				else
				{
					if((Math.abs(target.getX()-posX)<16)&&(posY-target.getY()<32)&&(posY-target.getY()>=0))
						closerTarget.add(target);
				}
					
			}
			break;
		case EAST:
			posX=(int)x;
			posY=(int)y;
			for(int i=0;i<Grid.objs.size();i++)
			{
				target = new ObjContainer(Grid.objs.get(i).getCoords(), Grid.objs.get(i).getType());
				if(target.getType()==OGGETTI.KEY)
				{
					if((Math.abs(target.getY()-posY)<4)&&(posX-target.getX()<8)&&(posX-target.getX()>=0))
						closerTarget.add(target);
				}
				else
				{
					if((Math.abs(target.getY()-posY)<16)&&(posX-target.getX()<32)&&(posX-target.getX()>=0))
						closerTarget.add(target);
				}
					
			}
			break;
		case WEST:
			posX=(int)x;
			posY=(int)y;
			for(int i=0;i<Grid.objs.size();i++)
			{
				target = new ObjContainer(Grid.objs.get(i).getCoords(), Grid.objs.get(i).getType());
				if(target.getType()==OGGETTI.KEY)
				{
					if((Math.abs(target.getY()-posY)<4)&&(target.getX()-posX<8)&&(target.getX()-posX>=0))
						closerTarget.add(target);
				}
				else
				{
					if((Math.abs(target.getY()-posY)<16)&&(target.getX()-posX<32)&&(target.getX()-posX>=0))
						closerTarget.add(target);
				}
					
			}
			break;
		}
		return selectTarget(closerTarget, x, y,direction);
	}
	
	private ObjContainer selectTarget(Vector<ObjContainer>closerTarget, float x, float y,POINTTO direction)
	{
		this.setInteger(x,y,direction);
		ObjContainer nearestTarget = new ObjContainer(-1,-1, null);
		double min=1000;
		for(int i=0;i<closerTarget.size();i++){
			if((Math.sqrt(Math.pow(closerTarget.get(i).getX()-posX, 2)
				+ Math.pow(closerTarget.get(i).getY()-posY, 2))<min))
			{
				min = Math.sqrt(Math.pow(closerTarget.get(i).getX()-posX, 2)
					+ Math.pow(closerTarget.get(i).getY()-posY, 2));
				nearestTarget=closerTarget.get(i);
			}
		}
		return nearestTarget;
	}
	
	private boolean isTooFar(float x,float y,POINTTO direction){
		this.setInteger(x,y,direction);
		switch(direction)
		{
		case NORTH:
			return(posY>target.getY());
		case SOUTH:
			return(posY<target.getY());
		case EAST:
			return(posX<target.getX());
		case WEST:
			return(posX>target.getX());
		}
		return true;
	}
	
	private void setInteger(float x, float y,POINTTO direction)
	{
		posX=(int)x;
		posY=(int)y;
	}
}
